// 引用axios
import axios from 'axios'
import { BASE_URL, OK } from './config'
import qs from 'qs'

// 自定义判断元素类型JS
function toType (obj) {
  return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
// 参数过滤函数
function filterNull (o) {
  for (var key in o) {
    if (o[key] === null) {
      delete o[key]
    }
    if (toType(o[key]) === 'string') {
      o[key] = o[key].trim()
    } else if (toType(o[key]) === 'object') {
      o[key] = filterNull(o[key])
    } else if (toType(o[key]) === 'array') {
      o[key] = filterNull(o[key])
    }
  }
  return o
}

/*
  接口处理函数
  这个函数每个项目都是不一样的，我现在调整的是适用于
  https://cnodejs.org/api/v1 的接口，如果是其他接口
  需要根据接口的参数进行调整。参考说明文档地址：
  https://cnodejs.org/topic/5378720ed6e2d16149fa16bd
  主要是，不同的接口的成功标识和失败提示是不一致的。
  另外，不同的项目的处理方法也是不一致的，这里出错就是简单的alert
*/
function apiAxios (method, vueInstance, url, params, success, failure, showLoading = true) {
  // 拼接参数
  if (params) {
    params = filterNull(params)
  }
  // if (showLoading) {
  //   vueInstance.$vux.loading.show({
  //     text: '加载中...',
  //     position: 'fixed'
  //   })
  // }
  let baseURL = BASE_URL
  if (url.indexOf('http') > 0) {
    baseURL = ''
  }
  axios({
    method: method,
    url: url,
    data: method === 'POST' || method === 'PUT' ? qs.stringify(params) : null,
    params: method === 'GET' || method === 'DELETE' ? params : null,
    baseURL: baseURL,
    withCredentials: false,
    timeout: 30000
  })
  .then(function (res) {
    if (showLoading) {
      vueInstance.$vux.loading.hide()
    }
    if (res.data.code === OK) {
      if (success) {
        success(res.data.data, res.data.total)
      }
    } else {
      if (failure) {
        failure(res.data)
      } else {
        vueInstance.$vux.toast.text(res.data.message, 'middle')
        console.error('api error: ' + res.data.message)
      }
    }
  })
  .catch(function (err) {
    if (showLoading) {
      vueInstance.$vux.loading.hide()
    }
    let errMsg = ''
    if (err && err.response) {
      switch (err.response.status) {
        case 400:
          errMsg = vueInstance.$t('toast.400')
          break
        case 401:
          errMsg = vueInstance.$t('toast.401')
          break
        case 403:
          errMsg = vueInstance.$t('toast.403')
          break
        case 404:
          errMsg = vueInstance.$t('toast.404')
          break
        case 408:
          errMsg = vueInstance.$t('toast.408')
          break
        case 500:
          errMsg = vueInstance.$t('toast.500')
          break
        case 501:
          errMsg = vueInstance.$t('toast.501')
          break
        case 502:
          errMsg = vueInstance.$t('toast.502')
          break
        case 503:
          errMsg = vueInstance.$t('toast.503')
          break
        case 504:
          errMsg = vueInstance.$t('toast.504')
          break
        case 505:
          errMsg = vueInstance.$t('toast.505')
          break
        default:
          errMsg = vueInstance.$t('toast.conFail', {
            errCode: err.response.status
          })
      }
    } else {
      // axios超时处理
      if (err.message.indexOf('timeout') > -1) {
        errMsg = '网络请求超时'
      } else {
        errMsg = vueInstance.$t('toast.conError', {
          errMsg: err.message.substring(0, 155)
        })
      }
    }
    if (failure) {
      failure(err.message)
    } else {
      vueInstance.$vux.toast.text(errMsg, 'middle')
    }
    if (err) {
      console.error('api error, HTTP CODE: ' + err.message)
    }
  })
}

// 返回在vue模板中的调用接口
export default {
  get: function (vueInstance, url, params, success, failure, showLoading) {
    return apiAxios('GET', vueInstance, url, params, success, failure, showLoading)
  },
  post: function (vueInstance, url, params, success, failure, showLoading) {
    return apiAxios('POST', vueInstance, url, params, success, failure, showLoading)
  },
  put: function (vueInstance, url, params, success, failure, showLoading) {
    return apiAxios('PUT', vueInstance, url, params, success, failure, showLoading)
  },
  delete: function (vueInstance, url, params, success, failure, showLoading) {
    return apiAxios('DELETE', vueInstance, url, params, success, failure, showLoading)
  }
}
